//
//  GoalSetupViewModel.swift
//  DaRings
//
//  Created by 魔样科技 on 2022/11/12.
//

import Foundation
import CRPSmartRing
import MYModule
import RxCocoa
import RxSwift
import SwiftDate
import ObjectiveC

class GoalSetupViewModel: NSObject {
    
    public let goalSetup = BehaviorRelay<GoalSetupModel>(value: GoalSetupModel())
    
    override init() {
        super.init()
        
        self.setupModelWithExcelNormalGoal()
        self.setupModelWithExcelweekDaysGoal()
        self.goalSetup.accept(self.model)
        
//        BluetoothManager.shared.getNormalTrainingGoal { [weak self] exerciseGoalsModel, error in
//            guard let self = self else { return }
//
//            self.excelNormalGoalsModel.step = exerciseGoalsModel.step
//            self.excelNormalGoalsModel.kcal = exerciseGoalsModel.kcal
//            self.excelNormalGoalsModel.exerciseTime = exerciseGoalsModel.exerciseTime
//            self.excelNormalGoalsModel.updateData()
//
//            self.setupModelWithExcelNormalGoal()
//            self.goalSetup.accept(self.model)
//        }
        
        BluetoothManager.shared.getTrainingDayGoal { exerciseGoalsStateModel, exerciseGoalsModel, error in
            
            self.excelTrainingDaysGoalModel.step = exerciseGoalsModel.step
            self.excelTrainingDaysGoalModel.kcal = exerciseGoalsModel.kcal
            self.excelTrainingDaysGoalModel.exerciseTime = exerciseGoalsModel.exerciseTime
            self.excelTrainingDaysGoalModel.open = NSNumber(value: exerciseGoalsStateModel.open) as! Int
            self.excelTrainingDaysGoalModel.weekDays = exerciseGoalsStateModel.weekday
            self.excelTrainingDaysGoalModel.updateData()
            
            self.setupModelWithExcelweekDaysGoal()
            self.goalSetup.accept(self.model)
        }
    }
    
    /// 假数据测试
    private func testData() {
        self.model.normalGoal.trainingModel.pickerModel.selectIndex = 2
        self.model.normalGoal.kcalModel.pickerModel.selectIndex = 1
        self.model.normalGoal.durationModel.pickerModel.selectIndex = 10
        self.model.normalGoal.durationModel.hourPickerModel.selectIndex = 25
        
        self.model.weeksGoal.isOpen = true
        self.model.weeksGoal.weeks = [0, 3, 5]
        self.model.weeksGoal.goalModel.trainingModel.pickerModel.selectIndex = 4
        self.model.weeksGoal.goalModel.kcalModel.pickerModel.selectIndex = 2
        self.model.weeksGoal.goalModel.durationModel.pickerModel.selectIndex = 2
        self.model.weeksGoal.goalModel.durationModel.hourPickerModel.selectIndex = 10
        self.goalSetup.accept(self.model)
    }
    
    /// 发送数据到设备
    public func setGoals() {
        if self.model.normalGoal.trainingModel.pickerModel.selectIndex > self.stepGoals.count - 1 {
            self.model.normalGoal.trainingModel.pickerModel.selectIndex = self.stepGoals.count - 1
        }
        self.excelNormalGoalsModel.step = Int(self.stepGoals[self.model.normalGoal.trainingModel.pickerModel.selectIndex]) ?? 0
        
        if self.model.normalGoal.kcalModel.pickerModel.selectIndex > self.kcalGoals.count - 1 {
            self.model.normalGoal.kcalModel.pickerModel.selectIndex = self.kcalGoals.count - 1
        }
        self.excelNormalGoalsModel.kcal = Int(self.kcalGoals[self.model.normalGoal.kcalModel.pickerModel.selectIndex]) ?? 0
        
        if self.model.normalGoal.durationModel.hourPickerModel.selectIndex > self.durationHourGoals.count - 1 {
            self.model.normalGoal.durationModel.hourPickerModel.selectIndex = self.durationHourGoals.count - 1
        }
        let normailHour = Int(self.durationHourGoals[self.model.normalGoal.durationModel.hourPickerModel.selectIndex]) ?? 0
        
        if self.model.normalGoal.durationModel.pickerModel.selectIndex > self.durationMinuteGoals.count - 1 {
            self.model.normalGoal.durationModel.pickerModel.selectIndex = self.durationMinuteGoals.count - 1
        }
        let normailMinute = Int(self.durationMinuteGoals[self.model.normalGoal.durationModel.pickerModel.selectIndex]) ?? 0
        self.excelNormalGoalsModel.exerciseTime = normailHour*60 + normailMinute
        
        if BluetoothManager.shared.deviceState == .connected {
            self.excelNormalGoalsModel.syncRecord = 1
        } else {
            self.excelNormalGoalsModel.syncRecord = 0
        }
        
        self.excelNormalGoalsModel.updateData()
        
        BluetoothManager.shared.setNormalTrainingGoal(CRPTrainingGoalsModel(step: self.excelNormalGoalsModel.step, kcal: self.excelNormalGoalsModel.kcal, distance: 0, exerciseTime: self.excelNormalGoalsModel.exerciseTime))
        
        if self.model.weeksGoal.goalModel.trainingModel.pickerModel.selectIndex > self.stepGoals.count - 1 {
            self.model.weeksGoal.goalModel.trainingModel.pickerModel.selectIndex = self.stepGoals.count - 1
        }
        self.excelTrainingDaysGoalModel.step = Int(self.stepGoals[self.model.weeksGoal.goalModel.trainingModel.pickerModel.selectIndex]) ?? 0
        
        if self.model.weeksGoal.goalModel.kcalModel.pickerModel.selectIndex > self.kcalGoals.count - 1 {
            self.model.weeksGoal.goalModel.kcalModel.pickerModel.selectIndex = self.kcalGoals.count - 1
        }
        self.excelTrainingDaysGoalModel.kcal = Int(self.kcalGoals[self.model.weeksGoal.goalModel.kcalModel.pickerModel.selectIndex]) ?? 0
        
        if self.model.weeksGoal.goalModel.durationModel.hourPickerModel.selectIndex > self.durationHourGoals.count - 1 {
            self.model.weeksGoal.goalModel.durationModel.hourPickerModel.selectIndex = self.durationHourGoals.count - 1
        }

        let weeksHour = Int(self.durationHourGoals[self.model.weeksGoal.goalModel.durationModel.hourPickerModel.selectIndex]) ?? 0
        
        if self.model.weeksGoal.goalModel.durationModel.pickerModel.selectIndex > self.durationMinuteGoals.count - 1 {
            self.model.weeksGoal.goalModel.durationModel.pickerModel.selectIndex = self.durationMinuteGoals.count - 1
        }
        let weeksMinute = Int(self.durationMinuteGoals[self.model.weeksGoal.goalModel.durationModel.pickerModel.selectIndex]) ?? 0
        self.excelTrainingDaysGoalModel.exerciseTime = weeksHour*60 + weeksMinute
        self.excelTrainingDaysGoalModel.open = NSNumber(value: self.model.weeksGoal.isOpen).intValue
        self.excelTrainingDaysGoalModel.weekDays = self.model.weeksGoal.weeks
        self.excelTrainingDaysGoalModel.updateData()

        // 更新今日活动目标
        let date = Date()
        let goalModel = ExerciseGoalsModel.currentGoal(weekDay: Date().weekday)
        let activityModel = ActivityModel.day(date: date)
        
        // TODO: 暂时不需要
        // 判断是否还需要弹出目标达成
//        if let activityModel = activityModel {
//            let achievementModel = DailyExerciseAchievement.current()
//            if goalModel.step != activityModel.step && activityModel.stepAchievement == 1 && achievementModel.stepAlertAble == false {
//                achievementModel.stepAlertAble = true
//            }
//            if goalModel.kcal != activityModel.calorie && activityModel.calorieAchievement == 1 && achievementModel.calorieAlertAble == false {
//                achievementModel.calorieAlertAble = true
//            }
//
//            if goalModel.exerciseTime != activityModel.time && activityModel.timeAchievement == 1 && achievementModel.timeAlertAble == false {
//                achievementModel.timeAlertAble = true
//            }
//            achievementModel.save()
//
//        }
        activityModel?.isTrainingDay = goalModel.isTrainingDay(date: date) == true ? 1 : 0
        activityModel?.goalStep = goalModel.step
        activityModel?.goalCalorie = goalModel.kcal
        activityModel?.goalTime = goalModel.exerciseTime
        activityModel?.updateData()
        

        BluetoothManager.shared.setTrainingDayGoal(CRPTrainingGoalStateModel(open: Bool(truncating: self.excelTrainingDaysGoalModel.open as NSNumber), weekday: self.excelTrainingDaysGoalModel.weekDays), CRPTrainingGoalsModel(step: self.excelTrainingDaysGoalModel.step, kcal: self.excelTrainingDaysGoalModel.kcal, distance: 0, exerciseTime: self.excelTrainingDaysGoalModel.exerciseTime))
    }
    
    private func setupModelWithExcelNormalGoal() {
        self.model.normalGoal.trainingModel.pickerModel.selectIndex = self.stepGoals.firstIndex(of: String(self.excelNormalGoalsModel.step)) ?? 0
        self.model.normalGoal.kcalModel.pickerModel.selectIndex = self.kcalGoals.firstIndex(of: String(self.excelNormalGoalsModel.kcal)) ?? 0
        
        if self.excelNormalGoalsModel.exerciseTime < 60 {
            self.model.normalGoal.durationModel.pickerModel.selectIndex = self.durationMinuteGoals.firstIndex(of: self.returnPickerObj(withTime: self.excelNormalGoalsModel.exerciseTime)) ?? 0
            self.model.normalGoal.durationModel.hourPickerModel.selectIndex = 0
        } else {
            let minute = self.excelNormalGoalsModel.exerciseTime%60
            self.model.normalGoal.durationModel.pickerModel.selectIndex = self.durationMinuteGoals.firstIndex(of: self.returnPickerObj(withTime: minute)) ?? 0
            
            let hour = Int(ceil(Double(self.excelNormalGoalsModel.exerciseTime/60)))
            self.model.normalGoal.durationModel.hourPickerModel.selectIndex = self.durationMinuteGoals.firstIndex(of: self.returnPickerObj(withTime: hour)) ?? 0
        }
    }
    
    private func setupModelWithExcelweekDaysGoal() {
        self.model.weeksGoal.isOpen = Bool(truncating:  self.excelTrainingDaysGoalModel.open as NSNumber)
        self.model.weeksGoal.weeks = self.excelTrainingDaysGoalModel.weekDays
        self.model.weeksGoal.goalModel.trainingModel.pickerModel.selectIndex = self.stepGoals.firstIndex(of: String(self.excelTrainingDaysGoalModel.step)) ?? 0
        self.model.weeksGoal.goalModel.kcalModel.pickerModel.selectIndex = self.kcalGoals.firstIndex(of: String(self.excelTrainingDaysGoalModel.kcal)) ?? 0
        
        if self.excelTrainingDaysGoalModel.exerciseTime < 60 {
            self.model.weeksGoal.goalModel.durationModel.pickerModel.selectIndex = self.durationMinuteGoals.firstIndex(of: self.returnPickerObj(withTime: self.excelTrainingDaysGoalModel.exerciseTime)) ?? 0
            self.model.weeksGoal.goalModel.durationModel.hourPickerModel.selectIndex = 0
        } else {
            let minute = self.excelTrainingDaysGoalModel.exerciseTime%60
            self.model.weeksGoal.goalModel.durationModel.pickerModel.selectIndex = self.durationMinuteGoals.firstIndex(of: self.returnPickerObj(withTime: minute)) ?? 0
            
            let hour = Int(ceil(Double(self.excelTrainingDaysGoalModel.exerciseTime/60)))
            self.model.weeksGoal.goalModel.durationModel.hourPickerModel.selectIndex = self.durationMinuteGoals.firstIndex(of: self.returnPickerObj(withTime: hour)) ?? 0
        }
    }
    
    private func returnPickerObj(withTime time: Int) -> String {
        var timeString = "\(time)"
        if time < 10 {
            timeString = "0\(time)"
        }
        return timeString
    }
    
    
    //MARK: - lazy load -
    public lazy var model: GoalSetupModel = {
        var model = GoalSetupModel()
        model.normalGoal = self.normalGoalModel
        model.weeksGoal = self.weekGoalModel
        
        return model
    }()
    
    public lazy var excelNormalGoalsModel: ExerciseGoalsModel = {
        let model = ExerciseGoalsModel.model(isNormal: true)
        return model
    }()
    
    public lazy var excelTrainingDaysGoalModel: ExerciseGoalsModel = {
        let model = ExerciseGoalsModel.model(isNormal: false)
        return model
    }()
    
    private lazy var normalGoalModel: NormalGoalModel = {
        let TrainingModel = GoalSetupNormalItemModel(title: "goal_setting_move_title".language, pickerModel: GoalSetupPickerModel(unit: "unit_step".language, pickerDataArray: self.stepGoals, selectIndex: 0, pickerWidth: 120))
        let kcalModel = GoalSetupNormalItemModel(title: "goal_setting_calories_title".language, pickerModel: GoalSetupPickerModel(unit: "unit_calorie".language, pickerDataArray: self.kcalGoals, selectIndex: 0, pickerWidth: 110))
        let durationModel = GoalSetupNormalItemModel(title: "goal_setting_exercise_title".language, pickerModel: GoalSetupPickerModel(unit: "unit_minute".language, pickerDataArray: self.durationMinuteGoals, selectIndex: 0, pickerWidth: 80), hourPickerModel: GoalSetupPickerModel(unit: "unit_upper_case_hour".language, pickerDataArray: self.durationHourGoals, selectIndex: 0, pickerWidth: 80))
        let normalModel = NormalGoalModel(trainingModel: TrainingModel, kcalModel: kcalModel, durationModel: durationModel)
        return normalModel
    }()
    
    private lazy var weekGoalModel: WeeksGoalModel = {
        let TrainingModel = GoalSetupNormalItemModel(title: "goal_setting_move_title".language, pickerModel: GoalSetupPickerModel(unit: "unit_step".language, pickerDataArray: self.stepGoals, selectIndex: 0, pickerWidth: 120))
        let kcalModel = GoalSetupNormalItemModel(title: "goal_setting_calories_title".language, pickerModel: GoalSetupPickerModel(unit: "unit_calorie".language, pickerDataArray: self.kcalGoals, selectIndex: 0, pickerWidth: 110))
        let durationModel = GoalSetupNormalItemModel(title: "goal_setting_exercise_title".language, pickerModel: GoalSetupPickerModel(unit: "unit_minute".language, pickerDataArray: self.durationMinuteGoals, selectIndex: 0, pickerWidth: 80), hourPickerModel: GoalSetupPickerModel(unit: "unit_upper_case_hour".language, pickerDataArray: self.durationHourGoals, selectIndex: 0, pickerWidth: 80))
        
        let todayNameInWeeks = Date().weekdayName(.short)
        let weeks = ["unit_week_full_1".language, "unit_week_full_2".language, "unit_week_full_3".language, "unit_week_full_4".language, "unit_week_full_5".language, "unit_week_full_6".language, "unit_week_full_7".language]
        let todayIndexInWeeks = weeks.firstIndex(of: todayNameInWeeks) ?? 0
        let weekModel = WeeksGoalModel(weeks: [todayIndexInWeeks], goalModel: NormalGoalModel(trainingModel: TrainingModel, kcalModel: kcalModel, durationModel: durationModel))
        return weekModel
    }()
    
    private lazy var stepGoals: [String] = {
        let array = [Int](4...35 ).map { $0 * 1000 }.map { String($0) }
        return array
    }()
    
    private lazy var kcalGoals: [String] = {
        let array = [Int](1...30).map { $0 * 100 }.map { String($0) }
        return array
    }()
    
    private lazy var durationMinuteGoals: [String] = {
        let array = [Int](0...59).map { String(format: "%02d", $0) }
        return array
    }()
    
    private lazy var durationHourGoals: [String] = {
        let array = [Int](0...10).map { String(format: "%02d", $0) }
        return array
    }()

}

